home *** CD-ROM | disk | FTP | other *** search
/ The Very Best of Atari Inside / The Very Best of Atari Inside 1.iso / mint / mint99s / intr.spp < prev    next >
Text File  |  1992-12-23  |  13KB  |  477 lines

  1. ; Copyright 1992 Eric R. Smith
  2. ; All rights reserved.
  3.  
  4. %include "magic.i"
  5. ;
  6. ; interrupt wrapping routines; these should just save registers and call
  7. ; the appropriate C handlers, unless speed is a major problem
  8. ;
  9.     TEXT
  10. ;
  11. ; first, utilities for setting processor status level
  12. ;
  13.     XDEF    _spl7,_spl
  14. _spl7:
  15.     move.w    sr,d0
  16.     ori.w    #$0700,sr
  17.     rts
  18. _spl:
  19.     move.w    4(sp),d0
  20.     move.w    d0,sr
  21.     rts
  22.  
  23.     XDEF    _mint_5ms
  24.     XDEF    _mint_timer
  25.     XDEF    _mint_vbl
  26.     XREF    _timeout    ; C time routine
  27.     XREF    _old_timer    ; old GEMDOS time vector
  28.     XREF    _old_vbl    ; old GEMDOS vbl vector
  29.     XREF    _old_5ms
  30.     XREF    _build_context
  31.     XREF    _restore_context
  32.     XREF    _proc_clock        ; controls process' allocation of CPU time
  33.     XREF    _curproc
  34.     XREF    _enter_kernel
  35.     XREF    _leave_kernel
  36.     XREF    _preempt
  37.     XREF    _in_kernel
  38.  
  39. ; AKP: this code is hit once every 5ms; it updates the time fields of curproc.
  40. _mint_5ms:
  41.     move.l    a0,-(sp)
  42.     move.l    _curproc,a0
  43.     tst.w    _in_kernel
  44.     bne.s    L_systime
  45.     lea    P_USRTIME(a0),a0    ; get offset to curproc->usrtime
  46.     addq.l    #5,(a0)            ; update the time
  47.     move.l    (sp)+,a0
  48.     move.l    _old_5ms+8,-(sp)    ; branch to old vector
  49.     rts
  50. L_systime:
  51.     lea    P_SYSTIME(a0),a0    ; get offset to curproc->systime
  52.     addq.l    #5,(a0)
  53.     move.l    (sp)+,a0
  54.     move.l    _old_5ms+8,-(sp)
  55.     rts
  56.  
  57. _mint_timer:
  58.     movem.l    d0-d2/a0-a2,-(sp)    ; save C registers
  59.     jsr    _timeout
  60.     movem.l    (sp)+,d0-d2/a0-a2
  61.     move.l    _old_timer+8,-(sp)    ; jump to GEMDOS time vector
  62.     rts
  63.  
  64. _mint_vbl:
  65. %ifndef ONLY030
  66.     tst.w    ($59e).w        ; test longframe (AKP)
  67.     beq.s    L_short1
  68. %endif
  69.     clr.w    -(sp)            ; yes, long frames: push a frame word
  70. L_short1:
  71.     pea    L_comeback        ; push fake PC
  72.     move.w    sr,-(sp)        ; push status register
  73.     move.l    _old_vbl+8,-(sp)    ; go service the interrupt
  74.     rts
  75.  
  76. L_comeback:
  77.     tst.w    _proc_clock        ; has time expired yet?
  78.     beq.s    L_expired        ; yes -- maybe go switch processes
  79. L_out:
  80.     rte                ; no -- just return
  81.  
  82. L_expired:
  83.     btst    #5,(sp)            ; user mode?
  84.     bne.s    L_out            ; no -- switching is not possible
  85.     tst.w    ($43e).w        ; test floppy disk lock variable
  86.     bne.s    L_out            ; if locked, can't switch
  87.     tst.w    _in_kernel        ; are we doing a kernel operation?
  88.     bne.s    L_out
  89. L_switch:
  90.     clr.w    -(sp)            ; no frame format needed
  91.     move.l    _curproc,-(sp)
  92.     addq.l    #P_CTXT0,(sp)            ; to get &curproc->ctxt[SYSCALL]
  93.     jsr    _build_context        ; build context
  94.     move.l    _curproc,a0
  95.     move.l    (a0),sp            ; use curproc->sysstack
  96.     jsr    _enter_kernel        ; enter kernel
  97.     jsr    _preempt        ; yield processor
  98.     ori.w    #$700,sr        ; spl7()
  99.     jsr    _leave_kernel        ; restore vectors
  100.     move.l    _curproc,a0
  101.     pea    4(a0)
  102.     jsr    _restore_context    ; back to user
  103.  
  104. ;
  105. ; reset routine -- called on a warm boot. Note that TOS sends the
  106. ; address to which we should return in register a6. Also note that
  107. ; the stack pointer is in an unknown state, so we set up our own
  108. ;
  109.     XDEF    _reset
  110.     XREF    _tmpstack        ; see main.c
  111.     XREF    _restr_intr
  112.  
  113. _reset:
  114.     move.w    #$2700,sr        ; avoid interruption here
  115.     move.l    sp,_tmpstack        ; save A7
  116.     lea    _tmpstack,sp        ; set up temporary stack
  117.     lea    256(sp),sp
  118.     movem.l    d0-d2/a0-a2,-(sp)    ; save C registers
  119.     jsr    _restr_intr        ; restore interrupts
  120.     movem.l    (sp)+,d0-d2/a0-a2    ; restore registers
  121.     move.l    _tmpstack,sp
  122.     jmp    (a6)            ; reset again
  123.  
  124. ;
  125. ; routine for doing a reboot
  126. ;
  127.     XDEF    _reboot
  128. _reboot:
  129.     move.w    #$2700,sr        ; avoid interrupts
  130.     move.l    (0).w,sp        ; get sp after reboot
  131.     move.l    (4).w,a6        ; get new reboot address
  132.     jmp    _reset
  133.  
  134. ;
  135. ; routine for mouse packet handling
  136. ;
  137.     XDEF    _newmvec
  138.     XDEF    _newjvec
  139.     XREF    _mouse_handler
  140. ; Experimental three button mouse support (by jr@ms.maus.de,
  141. ; August 4, 1992
  142. ;
  143. ; Should work with the mice shipped with Atari's ASV or
  144. ; compatible ones (like Golden Image GI-6000). Might not work
  145. ; on ST/STE systems with older IKBD's or keyboards. The middle mouse
  146. ; button is wired to one of the joystick directions on joystick one.
  147. ;
  148. ; _newmvec is the same as before with two exceptions:
  149. ; 1. the first byte of the packet is saved for the joystick handler
  150. ; 2. the bit for the middle mouse button is ored in
  151. ;
  152. ; _newjvec hooks into the joystick vector and chains to the normal
  153. ; handler. The middle mouse button state is saved in a special
  154. ; register for _newmvec, and a 'fake' mouse packet is set up
  155. ; (by merging the last mouse packet header, or-ing in the
  156. ; middle button state and using 0/0 for the x/y increment).
  157. ;
  158. ; the faked_packet and third_button variables are declared at the
  159. ; end of this file
  160.  
  161. _newmvec:
  162.     move.l    a0,-(sp)
  163.     move.b    (a0),d0
  164.     move.b    d0,faked_packet
  165.     or.b    third_button,d0
  166.     move.b    d0,(a0)
  167.     jsr    _mouse_handler
  168.     move.l    (sp)+,a0
  169.     rts
  170. ;
  171. ; routine for joystick packet handling (used for three button mice)
  172. ;
  173.     XDEF    _newjvec
  174.     XREF    _oldjvec
  175.  
  176. _newjvec:
  177.     move.l    a0,-(sp)    ; save a0 on the stack
  178.     move.b    2(a0),d0    ; joystick direction
  179.     and.b    #1,d0        ; middle mouse button in lowest bit
  180.     add.b    d0,d0        ; times 4
  181.     add.b    d0,d0
  182.     move.b    d0,third_button    ; save it for use in newmvec
  183.  
  184.     lea    faked_packet,a0    ; 'our' faked mouse event
  185.     move.b    (a0),d0
  186.     and.b    #$3,d0        ; unmask our mouse button
  187.     or.b    #$F8,d0        ; or in correct header
  188.     or.b    third_button,d0    ; or in the current status
  189.     move.b    d0,(a0)        ; write it back
  190.  
  191.     move.l    a0,-(sp)    ; pass pointer to fake packet
  192.     jsr    _mouse_handler    ; to \dev\mouse handler
  193.     addq.l    #4,sp        ; pop parameter
  194.     move.l    (sp)+,a0    ; restore original a0 value
  195.     move.l    _oldjvec,-(sp)    ; jump to original joystick handler
  196.     rts
  197. ;
  198. ; new ikbd keyboard interrupt vector
  199. ; kintr is a global variable that should be non-zero if a keyboard
  200. ; event occured
  201. ;
  202.     XDEF    _new_ikbd
  203.     XREF    _old_ikbd
  204.     XREF    _kintr
  205.  
  206. _new_ikbd:
  207.     move.w    #1,_kintr
  208.     move.l    _old_ikbd+8,-(sp)
  209.     rts            ; jump to system interrupt routine
  210.  
  211. ;
  212. ; simple signal handlers
  213. ; global variables referenced:
  214. ; in_kernel: (main.c): flag to indicate that we're in the MiNT kernel
  215. ; sig_routine: (signal.c): pointer to which signal catching routine to
  216. ;          call (e.g. for SIGBUS, or whatever)
  217. ;
  218.     XDEF    _new_bus,_new_addr,_new_ill,_new_divzero,_new_priv,_new_linef
  219.     XDEF    _new_trace,_new_chk,_new_trapv,_new_fpcp,_new_mmu,_new_pmmuacc
  220.     XDEF    _new_uninit,_new_spurious,_new_format,_new_cpv
  221.     XREF    _in_kernel,_sig_routine
  222.     XREF    _sigbus,_sigaddr,_sigill,_sigfpe,_sigpriv,_sigtrap
  223.     XREF    _haltformat,_haltcpv
  224.     XREF    _sig_exc
  225.     
  226. ;
  227. ; New bus error handler for memory protection: get the ssp and
  228. ; put it in the proc structure before calling
  229. ; _sigbus.  When the bus error happens in the kernel we don't save
  230. ; any contexts.
  231. ; We don't want to mess up any registers here because we might bring the
  232. ; page in and RTE.
  233. ;
  234.  
  235. _new_bus:
  236.     move.w    #$8,_sig_exc
  237.     move.l    #_mmu_sigbus,_sig_routine
  238. Do_sig:
  239.     move.l    a0,-(sp)        ; save a0
  240.     move.l    _curproc,a0
  241.     move.l    sp,P_EXCSSP(a0)
  242.     addq.l    #4,P_EXCSSP(a0)
  243.     move.l    6(sp),P_EXCPC(a0)
  244.     move.l    (sp)+,a0
  245.  
  246.     tst.w    _in_kernel        ; are we already in the kernel?
  247.     bne.s    Kernel            ; yes
  248.     move.w    _sig_exc,-(sp)
  249.     move.l    _curproc,-(sp)
  250.     addq.l    #4,(sp)            ; push offset of save area
  251.     jsr    _build_context
  252.     move.l    _curproc,a4
  253.     move.l    (a4),sp            ; put us in the system stack
  254.     jsr    _enter_kernel        ; set up kernel vectors
  255.     move.l    _sig_routine,a1        ; get signal handling routine
  256.     jsr    (a1)            ; go do it
  257.     ori.w    #$0700,sr        ; spl7()
  258.     jsr    _leave_kernel        ; leave kernel
  259.     addq.w    #4,a4            ; get context save area address
  260.     move.l    a4,-(sp)        ; push it
  261.     jsr    _restore_context    ; restore the context
  262. ;
  263. ; here's what we do if we already were in the kernel
  264. ;
  265. Kernel:
  266.     movem.l    d0-d2/a0-a2,-(sp)    ; save reggies
  267.     move.l    _sig_routine,a1        ; get handler
  268.     jsr    (a1)            ; go do it
  269.     movem.l    (sp)+,d0-d2/a0-a2
  270.     rte
  271.  
  272. ;
  273. ; _mmu_sigbus: a pre-handler for _sigbus.  Check the reason for the bus
  274. ; error and report if it was a real access fault.
  275. ;
  276. _mmu_sigbus:
  277.     move.l    a2,-(sp)
  278.     move.l    _curproc,a0
  279.     move.l    P_EXCSSP(a0),a1        ; a1 is now exception_ssp
  280.     move.w    $A(a1),d0        ; d0 is SSR
  281.     move.l    $10(a1),a1        ; a1 is the access address
  282.     move.l    a1,P_EXCADDR(a0)    ; save the access address
  283.  
  284.     ptestr    d0,(a1),#7,a2        ; a2 is the table address
  285.     move.l    a2,P_EXCTBL(a0)        ; save table address in curproc
  286.     pmove    psr,P_EXCMMUSR(a0)    ; save resulting mmusr in curproc
  287.     move.l    (sp)+,a2
  288.     jmp    _sigbus        ; chain to bus-error handler
  289.  
  290. _new_addr:
  291.     move.w    #$c,_sig_exc
  292.     move.l    #_sigaddr,_sig_routine
  293.     bra.s    Do_sig
  294. _new_ill:
  295.     move.w    #$10,_sig_exc
  296.     move.l    #_sigill,_sig_routine
  297.     bra.s    Do_sig            ; ASM pre-5.52.3 barfs on this :-(
  298. _new_divzero:
  299.     move.w    #$14,_sig_exc
  300.     move.l    #_sigfpe,_sig_routine
  301.     bra    Do_sig
  302. _new_linef:
  303.     move.w    #$2c,_sig_exc
  304.     move.l    #_sigill,_sig_routine
  305.     bra    Do_sig
  306. _new_chk:
  307.     move.w    #$18,_sig_exc
  308.     move.l    #_sigfpe,_sig_routine
  309.     bra    Do_sig
  310. _new_trapv:
  311.     move.w    #$1c,_sig_exc
  312.     move.l    #_sigfpe,_sig_routine
  313.     bra    Do_sig
  314. _new_fpcp:
  315. ; don't set _sig_exc - only needed for 68000 vectors
  316.     move.l    #_sigfpe,_sig_routine
  317.     bra    Do_sig
  318. _new_mmu:
  319. ; don't set _sig_exc - only needed for 68000 vectors
  320.     move.l    #_sigill,_sig_routine
  321.     bra    Do_sig
  322. _new_pmmuacc:
  323. ; don't set _sig_exc - only needed for 68000 vectors
  324.     move.l    #_sigbus,_sig_routine
  325.     bra    Do_sig
  326. _new_uninit:
  327.     move.w    #$3c,_sig_exc
  328.     move.l    #_sigbus,_sig_routine
  329.     bra    Do_sig
  330. _new_spurious:
  331.     move.w    #$60,_sig_exc
  332.     move.l    #_sigbus,_sig_routine
  333.     bra    Do_sig
  334. _new_format:
  335.     move.l    #_haltformat,_sig_routine
  336.     bra    Do_sig
  337. _new_cpv:
  338.     move.l    #_haltcpv,_sig_routine
  339.     bra    Do_sig
  340.  
  341.     XREF    _old_priv        ; old privilege violation vector
  342. _new_priv:
  343.     move.w    #$20,_sig_exc
  344.     move.l    #_sigpriv,_sig_routine
  345. %ifdef ONLY030
  346.     tst.w    ($59e).w        ; 68000s always get SIGPRIV
  347.     beq    Do_sig
  348. %endif
  349.     movem.l    d0/a0,-(a7)
  350.     move.l    10(a7),a0        ; fetch exception address
  351.     move.w    (a0),d0
  352.     and.w    #$ffc0,d0        ; partially decode move sr,...
  353.     cmp.w    #$40c0,d0        ; and test it
  354.     movem.l    (a7)+,d0/a0        ; preserves the flags
  355.     bne    Do_sig            ; doesn't look like sr,...
  356.     move.l    _old_priv+8,-(sp)    ; let our parent handle it
  357.     rts
  358.  
  359. ; XBRA vectors from main.c
  360.     XREF    _old_dos,_old_bios,_old_xbios
  361.     XREF    _old_divzero,_old_chk,_old_trapv
  362.  
  363. _new_trace:
  364.     btst    #5,(a7)            ; only check when called from supervisor mode
  365.     beq.s    S_1
  366.     cmp.l    #_old_dos+12,2(a7)    ; lets not trace the kernel !
  367.     beq.s    S_2
  368.     cmp.l    #_old_xbios+12,2(a7)
  369.     beq.s    S_2
  370.     cmp.l    #_old_bios+12,2(a7)
  371.     beq.s    S_2
  372.     cmp.l    #_old_divzero+12,2(a7)
  373.     beq.s    S_2
  374.     cmp.l    #_old_trapv+12,2(a7)
  375.     beq.s    S_2
  376.     cmp.l    #_old_chk+12,2(a7)
  377.     beq.s    S_2
  378. ; add any other non-traceable entities here...
  379.  
  380. S_1:    move.w    #$24,_sig_exc
  381.     move.l    #_sigtrap,_sig_routine
  382.     bra    Do_sig
  383.  
  384. S_2:    and.w    #$3fff,(a7)        ; clear both trace bits
  385.     rte                ; and re-start the handler
  386.  
  387. ;
  388. ; BIOS disk vectors for pseudo-disks like U: and X:; these are present
  389. ; just in case some program (foolishly) attempts to access these drives
  390. ; directly and gets horribly confused
  391. ;
  392.     XREF    _old_getbpb    ; old Getbpb vector
  393.     XREF    _old_mediach    ; old Mediach vector
  394.     XREF    _old_rwabs    ; old Rwabs vector
  395.     XREF    _aliasdrv    ; array of drive aliases
  396.     XDEF    _new_getbpb
  397.     XDEF    _new_mediach
  398.     XDEF    _new_rwabs
  399.  
  400. _new_getbpb:
  401.     move.w    4(sp),d0    ; check the drive
  402.     cmp.w    #$1f,d0        ; legal drive?
  403.     bhi.s    noalias0    ; no
  404.     move.w    d0,d1        ; get index
  405.     add.w    d0,d1        ; convert to index
  406.     lea    _aliasdrv,a0
  407.     move.w    0(a0,d1.w),d1    ; alias drive?
  408.     beq.s    noalias0
  409.     move.w    d1,d0
  410.     subq.w    #1,d0        ; adjust for aliasdrv base of '@'
  411.     cmp.w    #$1f,d0        ; is this a legal drive?
  412.     bhi.s    nobpb        ; no -- ignore it
  413. noalias0:
  414.     cmp.w    #$14,d0        ; drive U:?
  415.     beq.s    nobpb        ; yes, no BPB available
  416.     move.l    _old_getbpb+8,a0    ; not our drive
  417.     jmp    (a0)        ; call the old vector for it
  418. nobpb:
  419.     moveq.l    #0,d0        ; 0 means "no BPB read"
  420.     rts
  421.  
  422. _new_mediach:
  423.     move.w    4(sp),d0    ; check the drive
  424.     cmp.w    #$1f,d0        ; legal drive?
  425.     bhi.s    noalias1    ; no
  426.     move.w    d0,d1        ; get index
  427.     add.w    d0,d1        ; convert to index
  428.     lea    _aliasdrv,a0
  429.     move.w    0(a0,d1.w),d1    ; alias drive?
  430.     beq.s    noalias1
  431.     move.w    d1,d0
  432.     subq.w    #1,d0        ; adjust for aliasdrv base
  433.     cmp.w    #$1f,d0        ; legal drive?
  434.     bhi.s    nobpb        ; no -- ignore it
  435. noalias1:
  436.     cmp.w    #$14,d0        ; drive U:?
  437.     beq.s    nochng        ; yes, no change
  438.     move.l    _old_mediach+8,a0    ; not our drive
  439.     jmp    (a0)        ; call the old vector for it
  440. nochng:
  441.     moveq.l    #0,d0        ; 0 means "definitely no change"
  442.     rts
  443.  
  444. _new_rwabs:
  445.     move.w    $e(sp),d0    ; check the drive
  446.     cmp.w    #$1f,d0        ; legal drive?
  447.     bhi.s    noalias2    ; no
  448.     move.w    d0,d1        ; get index
  449.     add.w    d0,d1        ; convert to index
  450.     lea    _aliasdrv,a0
  451.     move.w    0(a0,d1.w),d1    ; alias drive?
  452.     beq.s    noalias2
  453.     move.w    d1,d0
  454.     subq.w    #1,d0        ; adjust for aliasdrv base
  455.     cmp.w    #$1f,d0        ; legal drive?
  456.     bhi.s    nobpb        ; no -- ignore it
  457. noalias2:
  458.     cmp.w    #$14,d0        ; drive U:?
  459.     beq.s    rwdone        ; yes, fake it
  460.     move.l    _old_rwabs+8,a0    ; not our drive
  461.     jmp    (a0)        ; call the old vector for it
  462. rwdone:
  463.     moveq.l    #0,d0        ; 0 means "successful operation"
  464.     rts
  465.  
  466.     DATA
  467. ; buffer for faked mouse packet (actually only 3 bytes)
  468.  
  469. faked_packet:
  470.     dc.l    0
  471.  
  472. ; here we store the additional button state
  473. third_button:
  474.     dc.w    0
  475.  
  476.     END
  477.